#ifndef SHADERLIBRARY_H
#define SHADERLIBRARY_H

#include "ngl/ShaderManager.h"
#include "ngl/Camera.h"
#include "ngl/Colour.h"

/// @file ShaderLibrary.h
/// @brief manages creation and use of shaders
/// @author Perseedoss Rajiv
/// @version 1.0
/// @date 29.03.11
/// Revision History :
/// Initial Version 29.03.11
/// @class ShaderLibrary
/// @brief liase with ngl::ShaderLib to provide higher level access and manipulation to/from shaders

class ShaderLibrary
{
public:
    /// @brief ctor
    ShaderLibrary();

    /// @brief dtor
    inline ~ShaderLibrary() { std::cout << "Shader Library deleted\n" << std::endl; }

    /// @brief update the view matrix of the shaders
    /// @param[in] _cam the camera that will be used to get the view matrix
    void updateView(ngl::Camera* _cam);

    /// @brief update the projection matrix of the shaders
    /// @param[in] _cam the camera that will be used to get the projection matrix
    void updateProjection(ngl::Camera* _cam);

    /// @brief update the view and projection matrices of the shaders
    /// @param[in] _cam the camera that will be used to get the matrices
    void updateViewProjection(ngl::Camera* _cam);

    /// @brief update the model matrix of the shaders
    /// @param[in] _matrix the model matrix to set to all the shaders
    void updateModel(const ngl::Matrix _matrix);

    /// @brief update the model matrix of a specific shader
    /// @param[in] _name the name of the shader to update
    /// @param[in] _matrix the model matrix to set to the shader
    /// @param[in] _exclusive flag to determine whether this method is called on its own
    void updateModel
                (
                    const std::string _name,
                    const ngl::Matrix _matrix,
                    const bool _exclusive = true
                );

    /// @brief update the colour parameter of a specific shader
    /// @param[in] _name the name of the shader to update
    /// @param[in] _colour the colour to set
    /// @param[in] _exclusive flag to determine whether this method is called on its own
    void updateColor
                    (
                        const std::string _name,
                        const ngl::Colour _colour,
                        const bool _exclusive = true
                    );

    /// @brief update the colour and model parameters of the shaders
    /// @param[in] _name the name of the shader to update
    /// @param[in] _matrix the model matrix to set to the shader
    /// @param[in] _colour the colour to set
    /// @param[in] _reset flag to set whether to flush shader states
    /// @param[in] _exclusive flag to determine whether to this shader as active
    void updateModelColor
                    (
                        const std::string _name,
                        const ngl::Matrix _matrix,
                        const ngl::Colour _colour,
                        const bool _reset = true,
                        const bool _exclusive = true
                    );

    /// @brief select a particular shader in the library as active
    /// @param[in] _name the name of the shader to set as active
    inline void useShader(const std::string _name) { m_shaders->useShader(_name); }

private:
    /// @brief the list of shaders
    ngl::ShaderManager* m_shaders;

    /// @brief the list of shader names
    std::vector<std::string> m_names;

};

#endif // SHADERLIBRARY_H
